package blazingbubble.graphics.game.renderer;

import blazingbubble.config.MultiplayerFieldInformation;
import blazingbubble.game.Field;
import blazingbubble.game.Game;
import blazingbubble.exception.StartupException;
import blazingbubble.config.Config;
import blazingbubble.game.Result;
import moltencore.network.protocol.PlayerData;
import spark.graphics.*;
import spark.graphics.scenegraph.SceneGraph;
import spark.exception.LoadingException;
import spark.graphics.scenegraph.SpriteNode;
import spark.graphics.scenegraph.TransformationNode;
import spark.graphics.scenegraph.TranslationNode;
import spark.math.Vector2;
import spark.math.Vector3;
import spark.utility.Clock;

import java.util.Iterator;
import java.util.Map;

public class GameRenderer {
	private FieldRenderer fieldRenderer = new FieldRenderer(Config.getSpriteMapsPath() + "/bubbles.sm", Config.getTexturesPath() + "/");
	private ISpriteMap spriteMap;
	private SpriteRenderable background;
	private SpriteRenderable foreground;
	private SpriteRenderable win;
	private SpriteRenderable lose;
	private Game game;
	private Font font;
	private MultiplayerFieldInformation multiplayerFieldInformation;
	private String timeLeftString;
	private int lastTimeLeftHundredthSeconds;

	public GameRenderer() {
	}

	public void startup(Game game, Config config) throws StartupException {
		try {
			this.game = game;
			String fieldIdent = Integer.toString(game.getFieldCount()) + Integer.toString(game.getTeamSize());
			this.multiplayerFieldInformation = config.getMultiplayerFieldInformation().get(fieldIdent);
			spriteMap = new SpriteMap(Config.getResourcePath() + multiplayerFieldInformation.getSpriteMap(), "default", Config.getTexturesPath() + "/");
			background = new SpriteRenderable();
			background.setSprite(spriteMap.getSprite("background"));
			background.setDimensions(new Vector2(25, 18.75f));
			foreground = new SpriteRenderable();
			foreground.setSprite(spriteMap.getSprite("foreground"));
			foreground.setDimensions(new Vector2(25, 18.75f));
			win = new SpriteRenderable();
			win.setSprite(spriteMap.getSprite("win"));
			win.setDimensions(new Vector2(256 / 32, 320 / 32));
			lose = new SpriteRenderable();
			lose.setSprite(spriteMap.getSprite("lose"));
			lose.setDimensions(new Vector2(256 / 32, 320 / 32));
			font = Font.makeFont(Config.getSpriteMapsPath() + "/manaspace.sm", Config.getTexturesPath() + "/");
		}
		catch(LoadingException e) {
			throw new StartupException(e);
		}
		fieldRenderer.startup();
	}

	public void prepareRender(SceneGraph graph) {
		TransformationNode backgroundTransformation = new TransformationNode(null, null, null);
		backgroundTransformation.addChild(new SpriteNode().registerForRendering(background));
		graph.getRoot().addChild(backgroundTransformation);
		int i = 0;
		for(Iterator<Field> fieldIterator = game.fieldIterator(); fieldIterator.hasNext();) {
			Field field = fieldIterator.next();
			fieldRenderer.prepareRender(field, getFieldResult(field), graph, multiplayerFieldInformation.getFieldInformation().get(i++));
		}
		TransformationNode foregroundTransformation = new TransformationNode(null, null, null);
		foregroundTransformation.addChild(new SpriteNode().registerForRendering(foreground));
		Float gameTimeLeft = game.getTimeLeft();
		if(gameTimeLeft != null) {
			int gameTimeLeftHundredthSeconds = (int)(gameTimeLeft * 100);
			if(lastTimeLeftHundredthSeconds != gameTimeLeftHundredthSeconds) {
				lastTimeLeftHundredthSeconds = gameTimeLeftHundredthSeconds;
				timeLeftString = Clock.secondsToString(gameTimeLeft);
			}
			foregroundTransformation.addChild(font.getText(timeLeftString));
		}
		graph.getRoot().addChild(foregroundTransformation);
	}

	private ISpriteRenderable getFieldResult(Field field) {
		ISpriteRenderable resultSprite = null;
		Result result = game.getFieldResult(field.getFieldId());
		if(result != null) {
			if(result == Result.Win) {
				resultSprite = win;
			}
			else {
				resultSprite = lose;
			}
		}
		return resultSprite;
	}

	public void shutdown() {
		fieldRenderer.shutdown();
	}
}
